/*
 * @Author: hongbin
 * @Date: 2022-01-12 15:34:17
 * @LastEditors: hongbin
 * @LastEditTime: 2022-01-12 17:15:30
 * @Description:盖房子
 */
import { FC, ReactElement, useEffect } from "react";
import * as THREE from "three";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
import { FontLoader } from "three/examples/jsm/loaders/FontLoader";
import { TextGeometry } from "three/examples/jsm/geometries/TextGeometry";
import ALFontJSON from "../assets/Alibaba PuHuiTi Light_Regular.json";
import DAT from "dat.gui";

interface IProps {}

const House: FC<IProps> = (): ReactElement => {
  useEffect(() => {
    const canvas = document.getElementById("canvas") as HTMLCanvasElement;
    let camera: THREE.PerspectiveCamera,
      controls: OrbitControls,
      scene: THREE.Scene,
      renderer: THREE.WebGLRenderer;
    const gui = new DAT.GUI();
    gui.close();
    const textureLoader = new THREE.TextureLoader();
    const bg1 = require("../assets/b1.jpg");
    const bg2 = require("../assets/b2.jpg");

    const texture1 = textureLoader.load(bg1);
    const texture2 = textureLoader.load(bg2);
    const caodi = textureLoader.load(require("../assets/caodi.jpg"));

    caodi.repeat.set(4, 4);
    caodi.wrapS = THREE.RepeatWrapping;
    caodi.wrapT = THREE.RepeatWrapping;

    const clock = new THREE.Clock();
    const sun = new THREE.PointLight(0xdddddd, 1);

    init();
    animate();

    // addItem();
    addLights();
    addPlane();
    addFont();

    house();
    function house() {
      const material = new THREE.MeshPhongMaterial({
        map: texture2,
      });
      const h = Math.random() * 10 + 10;
      const geometry = new THREE.CylinderGeometry(10, 10, h, 4, 1);
      const mesh = new THREE.Mesh(geometry, material);
      mesh.castShadow = true;
      scene.add(mesh);
    }

    function init() {
      scene = new THREE.Scene();
      scene.add(new THREE.AxesHelper(500));
      scene.background = new THREE.Color(0xcccccc);
      // 雾
      scene.fog = new THREE.FogExp2(0xcccccc, 0.002);

      renderer = new THREE.WebGLRenderer({ antialias: true, canvas });
      // 最多2倍像素
      renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
      renderer.setSize(window.innerWidth, window.innerHeight);
      //   document.body.appendChild(renderer.domElement);
      //允许阴影
      renderer.shadowMap.enabled = true;
      renderer.shadowMap.type = THREE.PCFSoftShadowMap;
      camera = new THREE.PerspectiveCamera(
        60,
        window.innerWidth / window.innerHeight,
        1,
        1000
      );
      //设置摄像头的位置
      camera.position.set(0, 50, 200);

      // controls

      controls = new OrbitControls(camera, renderer.domElement);
      controls.listenToKeyEvents(window as any); // optional

      //controls.addEventListener( 'change', render ); // call this only in static scenes (i.e., if there is no animation loop)

      controls.enableDamping = true; // an animation loop is required when either damping or auto-rotation are enabled
      //   controls.dampingFactor = 0.5;//阻尼惯性 需要一直开update

      controls.screenSpacePanning = false;

      // controls.minDistance = 10;
      // controls.minZoom = 10;
      // controls.maxDistance = 500;
      //可旋转角度
      // controls.maxPolarAngle = Math.PI / 2.2;

      window.addEventListener("resize", onWindowResize);
    }

    function addItem() {
      const material = new THREE.MeshPhongMaterial({
        color: 0xffffff,
        map: texture1,
      });

      for (let i = 0; i < 50; i++) {
        const h = Math.random() * 40 + 10;
        const geometry = new THREE.CylinderGeometry(10, 20, h, 4, 1);
        const mesh = new THREE.Mesh(geometry, material);
        mesh.position.x = Math.random() * 460 - 460 / 2;
        mesh.position.y = 0;
        mesh.position.z = Math.random() * 460 - 460 / 2;
        // mesh.updateMatrix();
        // mesh.matrixAutoUpdate = false;
        mesh.castShadow = true; //激活阴影
        scene.add(mesh);
      }
    }

    function addLights() {
      const dirLight1 = new THREE.DirectionalLight(0xdddddd, 1);
      dirLight1.position.set(1, 1, 1);
      scene.add(dirLight1);
      sun.position.set(100, 120, 5);
      sun.castShadow = true;
      sun.shadow.mapSize.width = 1024;
      sun.shadow.mapSize.height = 1024;
      sun.shadow.radius = 10;
      scene.add(sun);

      const dirLight2 = new THREE.DirectionalLight(0x002288);
      dirLight2.position.set(-1, -1, -1);
      scene.add(dirLight2);
      //背面的光
      const ambientLight = new THREE.AmbientLight(0x666666);
      scene.add(ambientLight);
    }

    //地面
    function addPlane() {
      const geometry = new THREE.PlaneGeometry(1000, 1000);
      const material = new THREE.MeshStandardMaterial({
        side: THREE.BackSide, //只有背面绘制 另一面不需要
        map: caodi,
      });
      const plane = new THREE.Mesh(geometry, material);
      geometry.rotateX(Math.PI / 2);
      //接收阴影
      plane.receiveShadow = true;
      plane.castShadow = true;
      geometry.center();
      scene.add(plane);
    }

    //文字
    function addFont() {
      const fontLoad = new FontLoader();

      const font = fontLoad.parse(ALFontJSON);
      if (font) {
        const geometry = new TextGeometry("抗美援朝，保家卫国", {
          font,
          size: 30,
          height: 5,
          curveSegments: 8,
          bevelEnabled: true,
          bevelThickness: 1.3,
          bevelSize: 0.5,
          bevelOffset: 0,
          bevelSegments: 5,
        });

        // const material = new THREE.MeshBasicMaterial({
        const material = new THREE.MeshPhongMaterial({
          map: texture1,
          //   normalMap: texture2,
          //   wireframe: true,
        });
        const text = new THREE.Mesh(geometry, material);
        text.translateY(30);
        geometry.center();
        text.position.z = -300;
        scene.add(text);
      }
    }

    function onWindowResize() {
      camera.aspect = window.innerWidth / window.innerHeight;
      camera.updateProjectionMatrix();

      renderer.setSize(window.innerWidth, window.innerHeight);
    }

    function animate() {
      requestAnimationFrame(animate);
      render();
      //   sunRun();
    }

    function render() {
      renderer.render(scene, camera);
    }
    //太阳运动
    function sunRun() {
      const elapsedTime = clock.getElapsedTime();
      sun.position.x = Math.cos(elapsedTime / 10) * 200;
    }
  }, []);

  return <canvas id='canvas'></canvas>;
};

export default House;
